# include <yolov8_yolo11_yolo12_det.h>
#include <opencv2/freetype.hpp>
#include <iostream>
#include <fstream>





int main(int argc, char** argv) {

	// 参数1:类别名的txt文件argv[5]
	// 参数2:engine文件路径
	// 参数3:读取mp4的路径
	// 参数4:是否 写入视频文件

	// 参数5:保存mp4文件路径
	// 参数6:中文字体路径
	// 参数7: 是否 实时处理显示

	// std::string label_map = "/root/UniSecurity/tensor02/c80.txt";
	// std::string yolo_engine_path = "/root/UniSecurity/t_tensorRT_yolov8/yolov8n.engine";
	// std::string videoPath = "/root/UniSecurity/tensor01/mp4_out/ce1.mp4";
	// bool save_mp4 = True;
	// std::string save_mp4_path = "/root/UniSecurity/tensor01/ce1.mp4";
	// std::string font_path = "/root/UniSecurity/opencv_chiese/chiese_hei.ttf";
	// bool show_mp4 = True;
	
	std::string label_map = argv[1];
	std::string yolo_engine_path = argv[2];
	std::string videoPath = argv[3];
	std::string save_mp4 = argv[4];
	std::string save_mp4_path = argv[5];
	std::string font_path = argv[6];
	// bool show_mp4 = argv[7];
	
	
	std::vector<std::string> classNames;
	std::ifstream fp(label_map);
	std::string name;
	while (!fp.eof()) {
		getline(fp, name);
		if (name.length()) {
			classNames.push_back(name);
		}
	}
	fp.close();
	std::shared_ptr<YOLOv81112TRTDetector> detector(new YOLOv81112TRTDetector());
	
	
	detector->initConfig(yolo_engine_path, 0.4, 0.25f);
	// cv::VideoCapture capture("/root/UniSecurity/tensor01/mp4_out/ce1.mp4");


	// 初始化FreeType字体
	auto ft = cv::freetype::createFreeType2();

	if (save_mp4=="1"){
		// 使用指定的.ttf字体文件路径
		ft->loadFontData(font_path, 0);
	}
	

	// 检测
    std::ifstream file(videoPath);
    if (!file.good()) {
        std::cerr << "视频文件不存在或路径错误: " << videoPath << std::endl;
        return -1;
    }

	cv::Mat frame;
	std::vector<DetectResult> results;

	
	// 
	cv::VideoCapture cap(videoPath);

	std::cout << "获取视频帧数 " << std::endl;
	// 获取视频属性
    int frameWidth = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));   // 视频宽度
    int frameHeight = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT)); // 视频高度
    int totalFrames = cap.get(cv::CAP_PROP_FRAME_COUNT);  					// 总帧数
    double fps = (int)cap.get(cv::CAP_PROP_FPS);                                 // 帧率（每秒帧数）
    // double duration = totalFrames / fps;                                    // 视频时长（秒）



	// 写入MP4文件，参数分别是：文件名，编码格式，帧率，帧大小  
	// cv::VideoWriter writer("out_n.mp4", cv::VideoWriter::fourcc('m','p','4','v'), 30, cv::Size(1920, 1080));
	cv::VideoWriter writer(save_mp4_path, cv::VideoWriter::fourcc('m','p','4','v'), fps, cv::Size(frameWidth, frameHeight));
	
	

	
	// 获取视频总帧数
	std::cout << "获取成功 " << totalFrames << std::endl;


	double num_time = 0.0;
	int num_i = 0;

	while (true) {

		num_i ++;
		int64 start4 = cv::getTickCount();

		bool ret = cap.read(frame);

		if (!ret) {
			// 处理读取失败的情况
			std::cout << "无法获取帧或已到达视频末尾" << std::endl;
			break;
		}
		if (frame.empty()) {
			break;
		}
		

		float t4 = (cv::getTickCount() - start4) / static_cast<float>(cv::getTickFrequency());
		int64 start5 = cv::getTickCount();

		detector->detect(frame, results);
		for (DetectResult dr : results) {
			cv::Rect box = dr.box;

			if (save_mp4=="1"){
				// 增加编码检查和调试输出
				std::string text = classNames[dr.classId];
				// 绘制矩形框：参数依次为(图像, 左上角点, 右下角点, 颜色, 线宽, 线条类型)
				// 这里使用红色(0,0,255)，线宽2，抗锯齿线条
				cv::rectangle(frame, 
							box.tl(),  // 左上角点
							box.br(),  // 右下角点
							cv::Scalar(0, 255, 0),  // 颜色（BGR格式，这里是红色）
							2,  // 线宽
							cv::LINE_AA);  // 线条类型（抗锯齿）

				// 使用FreeType2绘制中文字符
				// 参数说明：
				// frame: 要绘制文本的图像
				// text: 要显示的文本内容（如检测到的类别名）
				// cv::Point(box.tl().x, box.tl().y - 10): 文本左上角坐标（在检测框上方10像素处）
				// 12: 字体大小（像素值）
				// cv::Scalar(0, 0, 0): 文本颜色（黑色）
				// -1: 字体粗细（-1表示使用默认粗细）
				// cv::LINE_AA: 线条类型（抗锯齿）
				// false: 是否反转文本（false表示正常显示）
				ft->putText(frame, text, cv::Point(box.tl().x, box.tl().y - 10), 12, cv::Scalar(0, 0, 0),-1, cv::LINE_AA, false);

			}
			
		}


		// 	cv::imshow("YOLO12对象检测 + TensorRT10.8 ", frame);
		// 	char c = cv::waitKey(1);
		// 	if (c == 27) { // ESC 退出
		// 		break;
		// 	std::cout << "帧" << num_i << std::endl;
			
		// }
		
		

		if (num_i > 1){
			std::cout << "读图时间: " << t4*1000.0 << " 毫秒" << std::endl;
			float t5 = (cv::getTickCount() - start5) / static_cast<float>(cv::getTickFrequency());
			std::cout << "处理时间: " << t5*1000.0 << " 毫秒" << std::endl;

			float t6 = (cv::getTickCount() - start4) / static_cast<float>(cv::getTickFrequency());
			std::cout << "单帧总时间: " << t6*1000.0 << " 毫秒" << std::endl;

			num_time = num_time + t6;
		}

		
		if (save_mp4=="1"){
			// 写入视频
       		writer.write(frame);
		}
		
		// reset for next frame
		results.clear();
	}

	std::cout << "总帧数: " << totalFrames-1 << std::endl;
	std::cout << "平均每帧处理时间: " << num_time / (totalFrames-1) * 1000.0 << " 毫秒" << std::endl;

	return 0;
}
